home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / metamail / tahoe / quit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-18  |  7.2 KB  |  344 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifdef notdef
  14. static char sccsid[] = "@(#)quit.c    5.4 (Berkeley) 2/18/88";
  15. #endif /* notdef */
  16.  
  17. #include "rcv.h"
  18. #include <sys/stat.h>
  19. #include <sys/file.h>
  20.  
  21. /*
  22.  * Rcv -- receive mail rationally.
  23.  *
  24.  * Termination processing.
  25.  */
  26.  
  27. /*
  28.  * Save all of the undetermined messages at the top of "mbox"
  29.  * Save all untouched messages back in the system mailbox.
  30.  * Remove the system mailbox, if none saved there.
  31.  */
  32.  
  33. quit()
  34. {
  35.     int mcount, p, modify, autohold, anystat, holdbit, nohold;
  36.     FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf;
  37.     register struct message *mp;
  38.     register int c;
  39.     extern char tempQuit[], tempResid[];
  40.     struct stat minfo;
  41.     char *id;
  42.  
  43.     /*
  44.      * If we are read only, we can't do anything,
  45.      * so just return quickly.
  46.      */
  47.  
  48.     if (readonly)
  49.         return;
  50.     /*
  51.      * See if there any messages to save in mbox.  If no, we
  52.      * can save copying mbox to /tmp and back.
  53.      *
  54.      * Check also to see if any files need to be preserved.
  55.      * Delete all untouched messages to keep them out of mbox.
  56.      * If all the messages are to be preserved, just exit with
  57.      * a message.
  58.      *
  59.      * If the luser has sent mail to himself, refuse to do
  60.      * anything with the mailbox, unless mail locking works.
  61.      */
  62.  
  63.     fbuf = fopen(mailname, "r");
  64.     if (fbuf == NULL)
  65.         goto newmail;
  66.     flock(fileno(fbuf), LOCK_EX);
  67. #ifndef CANLOCK
  68.     if (selfsent) {
  69.         printf("You have new mail.\n");
  70.         fclose(fbuf);
  71.         return;
  72.     }
  73. #endif
  74.     rbuf = NULL;
  75.     if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) {
  76.         printf("New mail has arrived.\n");
  77.         rbuf = fopen(tempResid, "w");
  78.         if (rbuf == NULL || fbuf == NULL)
  79.             goto newmail;
  80. #ifdef APPEND
  81.         fseek(fbuf, mailsize, 0);
  82.         while ((c = getc(fbuf)) != EOF)
  83.             putc(c, rbuf);
  84. #else
  85.         p = minfo.st_size - mailsize;
  86.         while (p-- > 0) {
  87.             c = getc(fbuf);
  88.             if (c == EOF)
  89.                 goto newmail;
  90.             putc(c, rbuf);
  91.         }
  92. #endif
  93.         fclose(rbuf);
  94.         if ((rbuf = fopen(tempResid, "r")) == NULL)
  95.             goto newmail;
  96.         remove(tempResid);
  97.     }
  98.  
  99.     /*
  100.      * Adjust the message flags in each message.
  101.      */
  102.  
  103.     anystat = 0;
  104.     autohold = value("hold") != NOSTR;
  105.     holdbit = autohold ? MPRESERVE : MBOX;
  106.     nohold = MBOX|MSAVED|MDELETED|MPRESERVE;
  107.     if (value("keepsave") != NOSTR)
  108.         nohold &= ~MSAVED;
  109.     for (mp = &message[0]; mp < &message[msgCount]; mp++) {
  110.         if (mp->m_flag & MNEW) {
  111.             mp->m_flag &= ~MNEW;
  112.             mp->m_flag |= MSTATUS;
  113.         }
  114.         if (mp->m_flag & MSTATUS)
  115.             anystat++;
  116.         if ((mp->m_flag & MTOUCH) == 0)
  117.             mp->m_flag |= MPRESERVE;
  118.         if ((mp->m_flag & nohold) == 0)
  119.             mp->m_flag |= holdbit;
  120.     }
  121.     modify = 0;
  122.     if (Tflag != NOSTR) {
  123.         if ((readstat = fopen(Tflag, "w")) == NULL)
  124.             Tflag = NOSTR;
  125.     }
  126.     for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
  127.         if (mp->m_flag & MBOX)
  128.             c++;
  129.         if (mp->m_flag & MPRESERVE)
  130.             p++;
  131.         if (mp->m_flag & MODIFY)
  132.             modify++;
  133.         if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
  134.             id = hfield("article-id", mp);
  135.             if (id != NOSTR)
  136.                 fprintf(readstat, "%s\n", id);
  137.         }
  138.     }
  139.     if (Tflag != NOSTR)
  140.         fclose(readstat);
  141.     if (p == msgCount && !modify && !anystat) {
  142.         if (p == 1)
  143.             printf("Held 1 message in %s\n", mailname);
  144.         else
  145.             printf("Held %2d messages in %s\n", p, mailname);
  146.         fclose(fbuf);
  147.         return;
  148.     }
  149.     if (c == 0) {
  150.         if (p != 0) {
  151.             writeback(rbuf);
  152.             fclose(fbuf);
  153.             return;
  154.         }
  155.         goto cream;
  156.     }
  157.  
  158.     /*
  159.      * Create another temporary file and copy user's mbox file
  160.      * darin.  If there is no mbox, copy nothing.
  161.      * If he has specified "append" don't copy his mailbox,
  162.      * just copy saveable entries at the end.
  163.      */
  164.  
  165.     mcount = c;
  166.     if (value("append") == NOSTR) {
  167.         if ((obuf = fopen(tempQuit, "w")) == NULL) {
  168.             perror(tempQuit);
  169.             fclose(fbuf);
  170.             return;
  171.         }
  172.         if ((ibuf = fopen(tempQuit, "r")) == NULL) {
  173.             perror(tempQuit);
  174.             remove(tempQuit);
  175.             fclose(obuf);
  176.             fclose(fbuf);
  177.             return;
  178.         }
  179.         remove(tempQuit);
  180.         if ((abuf = fopen(mbox, "r")) != NULL) {
  181.             while ((c = getc(abuf)) != EOF)
  182.                 putc(c, obuf);
  183.             fclose(abuf);
  184.         }
  185.         if (ferror(obuf)) {
  186.             perror(tempQuit);
  187.             fclose(ibuf);
  188.             fclose(obuf);
  189.             fclose(fbuf);
  190.             return;
  191.         }
  192.         fclose(obuf);
  193.         close(creat(mbox, 0600));
  194.         if ((obuf = fopen(mbox, "r+")) == NULL) {
  195.             perror(mbox);
  196.             fclose(ibuf);
  197.             fclose(fbuf);
  198.             return;
  199.         }
  200.     }
  201.     if (value("append") != NOSTR) {
  202.         if ((obuf = fopen(mbox, "a")) == NULL) {
  203.             perror(mbox);
  204.             fclose(fbuf);
  205.             return;
  206.         }
  207.         fchmod(fileno(obuf), 0600);
  208.     }
  209.     for (mp = &message[0]; mp < &message[msgCount]; mp++)
  210.         if (mp->m_flag & MBOX)
  211.             if (send(mp, obuf, 0) < 0) {
  212.                 perror(mbox);
  213.                 fclose(ibuf);
  214.                 fclose(obuf);
  215.                 fclose(fbuf);
  216.                 return;
  217.             }
  218.  
  219.     /*
  220.      * Copy the user's old mbox contents back
  221.      * to the end of the stuff we just saved.
  222.      * If we are appending, this is unnecessary.
  223.      */
  224.  
  225.     if (value("append") == NOSTR) {
  226.         rewind(ibuf);
  227.         c = getc(ibuf);
  228.         while (c != EOF) {
  229.             putc(c, obuf);
  230.             if (ferror(obuf))
  231.                 break;
  232.             c = getc(ibuf);
  233.         }
  234.         fclose(ibuf);
  235.         fflush(obuf);
  236.     }
  237.     trunc(obuf);
  238.     if (ferror(obuf)) {
  239.         perror(mbox);
  240.         fclose(obuf);
  241.         fclose(fbuf);
  242.         return;
  243.     }
  244.     fclose(obuf);
  245.     if (mcount == 1)
  246.         printf("Saved 1 message in mbox\n");
  247.     else
  248.         printf("Saved %d messages in mbox\n", mcount);
  249.  
  250.     /*
  251.      * Now we are ready to copy back preserved files to
  252.      * the system mailbox, if any were requested.
  253.      */
  254.  
  255.     if (p != 0) {
  256.         writeback(rbuf);
  257.         fclose(fbuf);
  258.         return;
  259.     }
  260.  
  261.     /*
  262.      * Finally, remove his /usr/mail file.
  263.      * If new mail has arrived, copy it back.
  264.      */
  265.  
  266. cream:
  267.     if (rbuf != NULL) {
  268.         abuf = fopen(mailname, "r+");
  269.         if (abuf == NULL)
  270.             goto newmail;
  271.         while ((c = getc(rbuf)) != EOF)
  272.             putc(c, abuf);
  273.         fclose(rbuf);
  274.         trunc(abuf);
  275.         fclose(abuf);
  276.         alter(mailname);
  277.         fclose(fbuf);
  278.         return;
  279.     }
  280.     demail();
  281.     fclose(fbuf);
  282.     return;
  283.  
  284. newmail:
  285.     printf("Thou hast new mail.\n");
  286.     if (fbuf != NULL)
  287.         fclose(fbuf);
  288. }
  289.  
  290. /*
  291.  * Preserve all the appropriate messages back in the system
  292.  * mailbox, and print a nice message indicated how many were
  293.  * saved.  On any error, just return -1.  Else return 0.
  294.  * Incorporate the any new mail that we found.
  295.  */
  296. writeback(res)
  297.     register FILE *res;
  298. {
  299.     register struct message *mp;
  300.     register int p, c;
  301.     FILE *obuf;
  302.  
  303.     p = 0;
  304.     if ((obuf = fopen(mailname, "r+")) == NULL) {
  305.         perror(mailname);
  306.         return(-1);
  307.     }
  308. #ifndef APPEND
  309.     if (res != NULL)
  310.         while ((c = getc(res)) != EOF)
  311.             putc(c, obuf);
  312. #endif
  313.     for (mp = &message[0]; mp < &message[msgCount]; mp++)
  314.         if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
  315.             p++;
  316.             if (send(mp, obuf, 0) < 0) {
  317.                 perror(mailname);
  318.                 fclose(obuf);
  319.                 return(-1);
  320.             }
  321.         }
  322. #ifdef APPEND
  323.     if (res != NULL)
  324.         while ((c = getc(res)) != EOF)
  325.             putc(c, obuf);
  326. #endif
  327.     fflush(obuf);
  328.     trunc(obuf);
  329.     if (ferror(obuf)) {
  330.         perror(mailname);
  331.         fclose(obuf);
  332.         return(-1);
  333.     }
  334.     if (res != NULL)
  335.         fclose(res);
  336.     fclose(obuf);
  337.     alter(mailname);
  338.     if (p == 1)
  339.         printf("Held 1 message in %s\n", mailname);
  340.     else
  341.         printf("Held %d messages in %s\n", p, mailname);
  342.     return(0);
  343. }
  344.